package core.algorithm.operator.Crossover;

import core.algorithm.DecisionVariables.DecisionVariable;
import core.controllers.ControlDynamicParameters;
import core.problem.Individual;
import core.tools.MyMath.RandomGenerator;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author 郝国生 HAO Guo-Sheng
 */
public class RegularCrossover implements Crossover {

    @Override
    public List<Individual> getCrossoverResult(List<Individual> inputtedIndividual) {
        List<Individual> result = new LinkedList<>();
        int crossNumber = inputtedIndividual.size() / 2;
        boolean isOdd = (inputtedIndividual.size() % 2 != 0);
        //交叉前的个体
        int tem1 = 0, tem2 = 0;
        for (int i = 0; i < crossNumber; i++) {
            tem1 = RandomGenerator.getRandom(0, inputtedIndividual.size());
            do {//不让交叉的两个体相同
                tem2 = RandomGenerator.getRandom(0, inputtedIndividual.size());
            } while (tem1 == tem2);
            //一点交叉是产生一个随机数，进行一次交叉，多点交叉则产生多个随机数，进行多次一点交叉；
            if (RandomGenerator.nextDouble() <= ControlDynamicParameters.crossProbability) {
                List<DecisionVariable> crossedDecisionVariables = inputtedIndividual.get(tem1).getDecisionVariable().crossover(inputtedIndividual.get(tem2).getDecisionVariable());
                //借助两个临时变量，避免对原来的individual修改
                Individual ind1;
                try {
                    ind1 = inputtedIndividual.get(tem1).clone();
                    ind1.setDecisionVariable(crossedDecisionVariables.get(0));
                    Individual ind2 = inputtedIndividual.get(tem2).clone();
                    ind2.setDecisionVariable(crossedDecisionVariables.get(1));
                    result.add(ind1);
                    result.add(ind2);
                } catch (CloneNotSupportedException ex) {
                    Logger.getLogger(RegularCrossover.class.getName()).log(Level.SEVERE, null, ex);
                }

            } else {
                result.add(inputtedIndividual.get(tem1));
                result.add(inputtedIndividual.get(tem2));
            }
        }
        if (isOdd) {//再补充1个individual
            tem1 = RandomGenerator.getRandom(0, inputtedIndividual.size());
            do {//不让交叉的两个体相同                
                tem2 = RandomGenerator.getRandom(0, inputtedIndividual.size());
            } while (tem1 == tem2);
            List<DecisionVariable> crossedDecisionVariables = inputtedIndividual.get(tem1).getDecisionVariable().crossover(inputtedIndividual.get(tem2).getDecisionVariable());
            Individual ind1 = inputtedIndividual.get(tem1);
            ind1.setDecisionVariable(crossedDecisionVariables.get(0));
            result.add(ind1);
        }
        return result;
    }
}
